package com.lm.categories;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;


/**
 * The parser for the <b>categories.xml</b> document. All the categories are saved in the {@link List} of {@link XmlCategories} object.
 * This class is called only <i>one time</i>, when the application start.
 */
public class XmlCategoriesParser {
	static final String CATEGORIES = "categories";
	static final String CATEGORY = "category";
	static final String NAME = "name";
	static final String TOTALNAME = "totalName";
	static final String DESCRIPTORS = "descriptors";
	static final String DESCRIPTOR = "descriptor";
	
/************************* Parseur *************************/
	
	/**
	 * Open the <b>categories.xml</b> document and ans read its content.
	 * @param catFile
	 * 	The path of XML document
	 * @throws XMLStreamException
	 * @throws IOException
	 */
	public static void parse(String catFile) {
		XMLInputFactory factory = XMLInputFactory.newInstance();
		InputStream is = null;
		XMLStreamReader reader = null;
		try {			
			is = (new URL(catFile)).openConnection().getInputStream();
			reader = factory.createXMLStreamReader(is);
			readXmlCategories(reader);
		} catch (IOException | XMLStreamException e) {
			e.printStackTrace();
		} finally { // Close the flow
			try {
				reader.close();
				is.close();
			} catch (IOException | XMLStreamException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * Parse the XML document and give back the {@link XmlCategories} contained in the <b>categories.xml</b> file.
	 * The datas are put in the {@link XmlCategories} object (<i>Singleton</i>).
	 * @param reader
	 * 	The position of the parser.
	 * @throws XMLStreamException
	 */
	private static void readXmlCategories(XMLStreamReader reader) throws XMLStreamException {
		XmlCategories xmlCategories = null;
		
		String xmlCategoryName = "";
		List<XmlDescriptor> listXmlDescriptor = null;
		
		String xmlDescriptorTotalName = "";
		
		String tagContent = "";
		
		while(reader.hasNext()) {
			int event = reader.next();
			switch(event) {
			case XMLStreamConstants.START_ELEMENT:
				switch(reader.getLocalName()) {
				case CATEGORIES:
					xmlCategories = XmlCategories.getInstance();
					break;
//				case CATEGORY:
//					break;
//				case NAME:
//					break;
				case DESCRIPTORS:
					listXmlDescriptor = new ArrayList<XmlDescriptor>();
					break;
				case DESCRIPTOR:
					String xmlDescriptorTotalNameTmp = reader.getAttributeValue(null, TOTALNAME);
					if (xmlDescriptorTotalNameTmp != null) {
						xmlDescriptorTotalName = reader.getAttributeValue(null, TOTALNAME);
					} else {
						xmlDescriptorTotalName = "";
					}
					
					break;
				default:
					break;
				}
				break;
				 
			case XMLStreamConstants.CHARACTERS:
				tagContent = reader.getText().trim();
				break;
				 
			case XMLStreamConstants.END_ELEMENT:
				switch(reader.getLocalName()) {
//				case CATEGORIES:
//					break;
				case CATEGORY:
					xmlCategories.addCategory(new XmlCategory(xmlCategoryName, listXmlDescriptor));
					break;
				case NAME:
					xmlCategoryName = tagContent;
					break;
//				case DESCRIPTORS:
//					break;
				case DESCRIPTOR:
					if (!xmlDescriptorTotalName.equals("")) {
						listXmlDescriptor.add(new XmlDescriptor(tagContent, xmlDescriptorTotalName));
					} else {
						listXmlDescriptor.add(new XmlDescriptor(tagContent, tagContent));
					}
					
					break;
				default:
					break;
				}
				break;
				
			case XMLStreamConstants.START_DOCUMENT:
				xmlCategories = XmlCategories.getInstance();
				break;
				
			default:
				break;
			}
		}
	}
}
